/// <reference path="../devextreme/ts/jquery.d.ts" />
/// <reference path="../devextreme/ts/dx.all.d.ts" />

($ => {
    const invokeAction = (actionId, url, data, callback, options) => {
        let actionUrl = url;
        if (actionId) {
            actionUrl =
                actionUrl.indexOf('?') > -1
                    ? actionUrl + '&actionId=' + actionId
                    : actionUrl + '?actionId=' + actionId;
        }
        return new Promise(resolve => {
            if (window.yakeji.showLoading) {
                window.yakeji.showLoading();
            }
            $.ajax({
                type: 'POST',
                dataType: 'json',
                url: actionUrl,
                data: JSON.stringify(data),
                contentType: 'application/json;charset=UTF-8',
                success: result => {
                    if (window.yakeji.hideLoading) {
                        window.yakeji.hideLoading();
                    }
                    if (result.success) {
                        if (result.error) {
                            DevExpress.ui.dialog.alert(result.error, '提示');
                        }
                        resolve();
                        if (result.navigativeTo) {
                            navigativeTo(result, callback);
                        } else if (result.view) {
                            showView(result, url, data, callback, options);
                        } else if (result.nextAction) {
                            nextAction(result, url, data, callback, options);
                        } else if (result.skipAction) {
                            skipAction(result, url, data, callback, options);
                        } else if (result.nextApi) {
                            nextApi(result, url, data, callback, options);
                        } else if (result.skipApi) {
                            skipApi(result, url, data, callback, options);
                        } else {
                            showSuccessInfo(result).then(() => {
                                callback(result);
                            });
                        }
                    } else {
                        showErrorInfo(result, data);
                    }
                },
                error: () => {
                    if (window.yakeji.hideLoading) {
                        window.yakeji.hideLoading();
                    }
                    showErrorInfo({
                        error: '请求失败，请检查网络连接',
                    });
                },
                ...options,
            });
        });
    };

    const navigativeTo = (result, callback) => {
        if (result.navigativeTo) {
            window.open(result.navigativeTo, '_blank');
            callback(result);
        }
    };

    const showView = (result, url, data, callback, options) => {
        if (result.view) {
            let view = result.view;
            if (typeof view === 'string' || view instanceof String) {
                view = JSON.parse(view);
            }

            const $popup = $(`<div></div>`);

            $(document.body).append($popup);

            let amis = null;
            const popupOptions = {
                title: result.viewTitle ?? '对话框',
                showTitle: true,
                showCloseButton: true,
                visible: true,
                width: result.viewWidth || '50%',
                height: result.viewHeight || 'auto',
                minWidth: result.viewMinWidth || 400,
                maxHeight: result.viewMaxHeight || '90%',
                maxWidth: result.viewMaxWidth || undefined,
                minHeight: result.viewMinHeight || undefined,
                animation: null,
                toolbarItems: [],
                contentTemplate: container => {
                    $amis = $(`<div id='amis-renderer-${Date.now()}' /></div >`).appendTo(container);
                    amis = $amis.amis({
                        schema: view,
                        data: { ...data, ...result.data },
                        context: { ...result.content }
                    });
                },
                onHidden: () => {
                    amis.unmount();
                    $popup.remove();
                },
            };

            const getAmisForm = () => {
                return amis.getComponentByName(result.viewForm ?? 'form');
            };

            const getAmisData = () => {
                return {
                    ...(data ?? {}),
                    ...(getAmisForm()?.getValues() ?? {}),
                };
            };

            const validateAmisData = () => {
                return new Promise(resolve => {
                    const form = getAmisForm();
                    if (form) {
                        form.validate().then(result => {
                            if (result) {
                                resolve();
                            }
                        });
                    } else {
                        resolve();
                    }
                });
            };

            if (result.nextAction || result.nextApi) {
                popupOptions.toolbarItems.push({
                    widget: 'dxButton',
                    toolbar: 'bottom',
                    location: 'after',
                    options: {
                        text: result.nextActionCaption ?? '确定',
                        type: 'default',
                        onClick: () => {
                            validateAmisData().then(() => {
                                const action = result.nextAction ? nextAction : nextApi;
                                action(result, url, getAmisData(), callback, options).then(() => {
                                    $popup.dxPopup('hide');
                                });
                            });
                        },
                    },
                });
            }

            if (result.skipAction || result.skipApi) {
                popupOptions.toolbarItems.push({
                    widget: 'dxButton',
                    toolbar: 'bottom',
                    location: 'before',
                    options: {
                        text: result.skipActionCaption ?? '跳过',
                        type: 'danger',
                        onClick: () => {
                            const action = result.skipAction ? skipAction : skipApi;
                            action(result, url, getAmisData(), callback, options).then(() => {
                                $popup.dxPopup('hide');
                            });
                        },
                    },
                });
            }

            popupOptions.toolbarItems.push({
                widget: 'dxButton',
                toolbar: 'bottom',
                location: 'after',
                options: {
                    text: (result.nextAction || result.nextApi) ? '取消' : '关闭',
                    type: 'danger',
                    onClick: () => {
                        $popup.dxPopup('hide');
                    },
                },
            });

            $popup.dxPopup(popupOptions);
        }
    };

    const nextAction = (result, url, data, callback, options) => {
        if (result.nextAction) {
            return invokeAction(
                result.nextAction,
                options.actionUrl ?? url,
                { ...data },
                callback,
                options
            );
        }
    };

    const skipAction = (result, url, data, callback, options) => {
        if (result.skipAction) {
            return invokeAction(
                result.skipAction,
                options.actionUrl ?? url,
                { ...data },
                callback,
                options
            );
        }
    };

    const nextApi = (result, url, data, callback, options) => {
        if (result.nextApi) {
            return invokeAction(
                'NextApi',
                result.nextApi,
                { ...data },
                callback,
                options
            );
        }
    };

    const skipApi = (result, url, data, callback, options) => {
        if (result.skipApi) {
            return invokeAction(
                'SkipApi',
                result.skipApi,
                { ...data },
                callback,
                options
            );
        }
    };

    const showSuccessInfo = result => {
        return new Promise(resolve => {
            if (result.success) {
                if (result.info) {
                    if (result.info !== 'null') { DevExpress.ui.notify(result.info, 'success') };
                    resolve();
                } else if (result.warning) {
                    DevExpress.ui.dialog.alert(result.warning, '操作成功').then(resolve);
                } else {
                    DevExpress.ui.notify('操作成功', 'success');
                    resolve();
                }
            }
        });
    };

    const showErrorInfo = (result, data) => {
        if (!result.success) {
            if (result.view) {
                showView(result, null, data);
            } else if (result.error) {
                DevExpress.ui.dialog.alert(result.error, '操作失败');
            } else {
                DevExpress.ui.notify('操作失败', 'error');
            }
        }
    };

    $.invokeAction = (actionId, url, data, options) => {
        return new Promise(resolve => {
            invokeAction(
                actionId,
                url,
                data,
                result => {
                    resolve(result);
                },
                options || {}
            );
        });
    };
})(jQuery);
